// main.js

// Modules to control application life and create native browser window
const { app, BrowserWindow, ipcMain, dialog, Menu, MessageChannelMain } = require('electron')
const path = require('node:path')

const createWindow = () => {
  // 浏览器实例
  const win1 = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
        // 预加载脚本
        // 这里使用了两个Node.js概念：
        // - __dirname 字符串指向当前正在执行脚本的路径 (在本例中，它指向你的项目的根文件夹)。
        // - path.join API 将多个路径联结在一起，创建一个跨平台的路径字符串。
        // 将脚本附在渲染进程上，在 BrowserWindow 构造器中使用 webPreferences.preload 传入脚本的路径。
        preload: path.join(__dirname, 'preload.js')
    }
  })

  // 模式 3：主进程到渲染器进程
  const menu = Menu.buildFromTemplate([
    {
      label: app.name,
      submenu: [
        {
          click: () => win1.webContents.send('update-counter', 1),
          label: 'Increment'
        },
        {
          click: () => win1.webContents.send('update-counter', -1),
          label: 'Decrement'
        }
      ]
    }
  ])
  Menu.setApplicationMenu(menu)

  // 加载 index.html
  win1.loadFile('index.html')

  // win.loadURL('http://...')

  // 检查 内置浏览器是否支持 Autofill
  win1.webContents.on('did-finish-load', () => {
    win1.webContents.executeJavaScript(`
      if ('Autofill' in window) {
        console.log('Autofill is available');
      } else {
        console.log('Autofill is not available');
      }
    `);
  });
  // 打开开发工具
  win1.webContents.openDevTools()
}

// 这段程序将会在 Electron 结束初始化
// 和创建浏览器窗口的时候调用
// 部分 API 在 ready 事件触发后才能使用。
app.whenReady().then( () => {
  ipcMain.handle('pinggg', () => '我是主进程，返回：pong')
  ipcMain.handle('我是渲染线程传的参数', () => '主进程返回的数据')
  // // 模式 1：渲染器进程到主进程（单向）
  // ipcMain.on('set-title', (event, title) => {
  //   // 回调函数
  //   // 找到附加到消息发送方的 BrowserWindow 实例
  //   const webContents = event.sender
  //   const win = BrowserWindow.fromWebContents(webContents)
  //   win.setTitle(title)
  // })
  // 模式 1：渲染器进程到主进程（单向）
  ipcMain.on('set-title', handleSetTitle)
  // 模式 2：渲染器进程到主进程（双向）
  ipcMain.handle('dialog:openFile', handleFileOpen)
  // 模式 3：主进程到渲染器进程
  ipcMain.on('counter-value', (_event, value) => {
    console.log(value) // will print value to Node console
  })

  // 在 Electron 中，只有在 app 模块的 ready 事件触发后才能创建 BrowserWindows 实例。 
  // 您可以通过使用 app.whenReady() API 来监听此事件，并在其成功后调用 createWindow() 方法。
  createWindow()
  
  app.on('activate', () => {
    // 在 macOS 系统内, 如果没有已开启的应用窗口
    // 点击托盘图标时通常会重新创建一个新窗口
    // 即使没有打开任何窗口，macOS 应用通常也会继续运行。 在没有窗口可用时调用 app 会打开一个新窗口。
    // 为了实现这一特性，可以监听模组的 activate 事件，如果没有任何活动的 BrowserWindow，调用 createWindow() 方法新建一个。
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// 除了 macOS 外，当所有窗口都被关闭的时候退出程序。 因此, 通常
// 对应用程序和它们的菜单栏来说应该时刻保持激活状态, 
// 直到用户使用 Cmd + Q 明确退出
// 关闭所有窗口时退出应用 (Windows & Linux)
// 此方法不适用于 macOS。
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit()
})

// 在当前文件中你可以引入所有的主进程代码
// 也可以拆分成几个文件，然后用 require 导入。


// 模式 1：渲染器进程到主进程（单向）
function handleSetTitle (event, title) {
  const webContents = event.sender
  const win = BrowserWindow.fromWebContents(webContents)
  win.setTitle(title)
}
// 模式 2：渲染器进程到主进程（双向）
async function handleFileOpen () {
  // 需要 dialog 
  const { canceled, filePaths } = await dialog.showOpenDialog()
  if (!canceled) {
    return filePaths[0]
  }
}